<!--
*@Author: zt
*@Description: 会议室自定义日历组件
*@Date: 2024-07-12 10:34:41
-->
<template>
  <a-layout class="u-custom-calender f-h-100">
    <a-layout-header
      style="background-color: #fff; height: auto; padding: 0 14px"
    >
      <a-row align="middle" :justify="toolJustify">
        <a-col justify="center">
          <a-space style="color: #aaa" size="middle">
            <a-space style="color: #aaa" v-if="showExchange">
              <LeftOutlined class="u-exchange-icon" @click="beforeAndNext(1)" />
              {{ viewValue }}
              <RightOutlined
                class="u-exchange-icon"
                @click="beforeAndNext(2)"
              />
            </a-space>
          </a-space>
        </a-col>
        <a-col flex="1" align="end" v-if="showExtraTool">
          <slot name="extra"></slot>
          <a-radio-group v-model:value="calenderType">
            <a-radio-button value="day">日</a-radio-button>
            <a-radio-button value="week">周</a-radio-button>
            <a-radio-button value="month">月</a-radio-button>
          </a-radio-group>
        </a-col>
      </a-row>
    </a-layout-header>
    <a-layout-content>
      <div
        style="width: 100%; height: 100%; padding: 0 20px"
        ref="contentBoxRef"
      >
        <u-table
          :columns="columns"
          :data="tabData"
          :pagination="false"
          class="u-day-week-table"
          :scroll="{ y: 'calc(100vh - 40vh)' }"
        ></u-table>
      </div>
    </a-layout-content>
  </a-layout>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, onMounted, h, watch } from 'vue';
import * as meetRoomApi from '@/service/administration/meet/room/index';
import { numberC } from '@/util/common';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import { TableColumnProps } from 'ant-design-vue';
dayjs.locale('zh-cn');

interface Props {
  data?: Array<any>;
  showExtraTool?: boolean;
  showViewYear?: boolean;
  showExchange?: boolean;
  toolJustify?: string;
  calendarType?: string;
  extraLessH?: number; // 额外需要减的高度
}
const props = withDefaults(defineProps<Props>(), {
  showExtraTool: true,
  showViewYear: true,
  showExchange: true,
  toolJustify: '',
  calendarType: 'month',
  extraLessH: 0,
});

// 日历类型  day、week、month
let calenderType = ref<string>(props.calendarType);
const tabData = ref([]);
let originCols = reactive<Array<TableColumnProps>>([
  {
    dataIndex: 'index',
    title: '序号',
    width: 60,
    align: 'center',
    customRender: ({ text, record, index }) => {
      return index + 1;
    },
  },
  { title: '会议室名称', dataIndex: 'conName', width: 150, align: 'center' },
]);
let columns = reactive<Array<TableColumnProps>>([]);

// 当前选中的日期
let dateValue = ref<Dayjs>(dayjs(new Date()).format('YYYY-MM-DD'));
// 展示的日期
let viewValue = computed(() => {
  if (calenderType.value == 'month') {
    return dayjs(dateValue.value).format('YYYY年MM月');
  } else if (calenderType.value == 'week') {
    let dayW = dayjs(dateValue.value).day();
    return (
      dayjs(dayjs(dateValue.value).subtract(dayW - 1, 'day')).format(
        'YYYY年MM月DD日'
      ) +
      '-' +
      dayjs(dayjs(dateValue.value).add(7 - dayW, 'day')).format('MM月DD日')
    );
  } else if (calenderType.value == 'day') {
    return dayjs(dateValue.value).format('YYYY年MM月DD日');
  }
});

onMounted(async () => {
  initColumns();
  initTabDatas();
  initWorkDatas();

  await getSearch('month');
});

// 初始化日常的数据
const initWorkDatas = () => {};

// 获取当日议程
const getWorkDate = () => {};

// 渲染日，周的单元格
const renderDayWeekCel = (text, record, index, column) => {
  let nowTime = dayjs().format('YYYY-MM-DD');
  let timeFlag = false;
  if (nowTime == dayjs(record.date).format('YYYY-MM-DD')) {
    const nowHour = dayjs().format('YYYY-MM-DD HH:mm:ss');
    const startHour = record.startHour.split('-')[0];
    const startTime =
      dayjs(record.date).format('YYYY-MM-DD') + ' ' + startHour + ':00';
    timeFlag = dayjs(nowHour).isBefore(startTime);
  } else {
    timeFlag = dayjs(nowTime).isBefore(record.date);
  }
  let newArr = [];
  //在表格内循环渲染数据
  record.textArr.forEach(item => {
    if (item.meetName) {
      for (let key in item) {
        //当且仅当字段dataIndex的值一样时才进行渲染数据
        if (key == column['dataIndex']) {
          newArr.push(
            h(
              'div',
              {
                style: {
                  height: '100%',
                  borderLeft: `2px solid ${timeFlag ? '#52C41A' : '#1890FF'}`,
                  marginBottom: '5px',
                },
              },
              h(
                'div',
                { style: { height: '100%', marginLeft: '5px' } },
                item.meetName
              ),
              h(
                'div',
                { style: { height: '100%', marginLeft: '5px' } },
                item.startHour
              )
            )
          );
        }
      }
    }
  });
  // 返回渲染数据
  return h(
    'div',
    {
      class: 'u-calender-cell-work',
      style: {
        '--fc': timeFlag ? '#52C41A' : '#1890FF',
        '--bg': timeFlag ? '#E7F4FF ' : '#E8F8E0',
        '--brg': timeFlag ? '#52C41A' : '#1890FF',
      },
    },
    newArr
  );
};
// 初始化表头
const initColumns = () => {
  columns.splice(0, columns.length, ...originCols);
  if (calenderType.value == 'day') {
    for (let i = 0; i <= 23; i++) {
      columns.push({
        title: i < 10 ? '0' + i.toString() + ':00' : i.toString() + ':00',
        dataIndex: 'dcol' + i,
        width: 200,
        customRender: ({ text, record, index, column }) => {
          return renderDayWeekCel(text, record, index, column);
        },
      });
    }
  } else if (calenderType.value == 'week') {
    let nowDay = numberC(dayjs(dateValue.value));
    let startDayOfMonth = dayjs(dateValue.value).subtract(
      nowDay == 0 ? 6 : nowDay
    );
    for (let i = 0; i <= 6; i++) {
      // 表头-周排列
      const label = {
        1: '周一',
        2: '周二',
        3: '周三',
        4: '周四',
        5: '周五',
        6: '周六',
        7: '周日',
      };
      columns.push({
        title: label[i + 1],
        dataIndex: 'wcol' + (i + 1),
        customRender: ({ text, record, index, column }) => {
          return renderDayWeekCel(text, record, index, column);
        },
      });
    }
  } else if (calenderType.value == 'month') {
    let maxDay = dayjs(dateValue.value).endOf('month').format('DD');
    let startDayOfMonth = dayjs(dateValue.value).startOf('month');
    for (let i = 0; i < numberC(maxDay); i++) {
      let nowDate = startDayOfMonth.add(i, 'day');
      let dayDate = nowDate.format('MM/DD');
      let weekDate = nowDate.format('dddd');
      columns.push({
        title: dayDate + '(' + weekDate + ')',
        dataIndex: 'mcol' + (i + 1),
        width: 200,
        customRender: ({ text, record, index, column }) => {
          return renderDayWeekCel(text, record, index, column);
        },
      });
    }
  }
};

//获取数据
const getSearch = async (dataFormat?: string) => {
  tabData.value = [];
  if (dataFormat == 'month') {
    const res = await meetRoomApi.SelectUse({
      pageStatus: 1,
      queryDate: dayjs(dateValue.value).format('YYYY-MM'),
    });
    if (res.code == 0) {
      const arr = res.data;
      const seenKeyids = new Set<number>();
      arr.map(e => {
        let startHour =
          dayjs(e.startTime).format('HH:mm') +
          '-' +
          dayjs(e.endTime).format('HH:mm');
        // 判断是否数据的keyid存在，存在将数据合并到最开始出现的数据的textarr字段里，不存在则将新增keyid并添加数据到textarr
        if (seenKeyids.has(e.keyid)) {
          tabData.value.forEach(item => {
            if (item.keyid == e.keyid) {
              item.textArr.push({
                keyid: e.keyid,
                conName: e.conName,
                meetName: e.meetName,
                ['mcol' + Number(dayjs(e.startTime).format('DD'))]: e.meetName,
                date: dayjs(e.startTime).format('YYYY-MM-DD'),
                startHour: startHour,
              });
            }
          });
        } else {
          seenKeyids.add(e.keyid);
          tabData.value.push({
            keyid: e.keyid,
            conName: e.conName,
            ['mcol' + Number(dayjs(e.startTime).format('DD'))]: e.meetName,
            date: dayjs(e.startTime).format('YYYY-MM-DD'),
            startHour: startHour,
            textArr: [
              {
                keyid: e.keyid,
                conName: e.conName,
                meetName: e.meetName,
                ['mcol' + Number(dayjs(e.startTime).format('DD'))]: e.meetName,
                date: dayjs(e.startTime).format('YYYY-MM-DD'),
                startHour: startHour,
              },
            ],
          });
        }
      });
    }
  } else if (dataFormat == 'week') {
    let dayW = dayjs(dateValue.value).day();
    const res = await meetRoomApi.SelectUse({
      pageStatus: 2,
      queryStartDate: dayjs(
        dayjs(dateValue.value).subtract(dayW - 1, 'day')
      ).format('YYYY-MM-DD'),
      queryDate: dayjs(dayjs(dateValue.value).add(7 - dayW, 'day')).format(
        'YYYY-MM-DD'
      ),
    });
    if (res.code == 0) {
      const arr = res.data;
      const seenKeyids = new Set<number>();
      arr.map(e => {
        let datas = dayjs(e.startTime).day();
        let startHour =
          dayjs(e.startTime).format('HH:mm') +
          '-' +
          dayjs(e.endTime).format('HH:mm');
        // 判断是否数据的keyid存在，存在将数据合并到最开始出现的数据的textarr字段里，不存在则将新增keyid并添加数据到textarr
        if (seenKeyids.has(e.keyid)) {
          tabData.value.forEach(item => {
            if (item.keyid == e.keyid) {
              item.textArr.push({
                keyid: e.keyid,
                conName: e.conName,
                meetName: e.meetName,
                ['wcol' + Number(datas)]: e.meetName,
                date: dayjs(e.startTime).format('YYYY-MM-DD'),
                startHour: startHour,
              });
            }
          });
        } else {
          seenKeyids.add(e.keyid);
          tabData.value.push({
            conName: e.conName,
            ['wcol' + Number(datas)]: e.meetName,
            date: dayjs(e.startTime).format('YYYY-MM-DD'),
            startHour: startHour,
            keyid: e.keyid,
            textArr: [
              {
                keyid: e.keyid,
                conName: e.conName,
                meetName: e.meetName,
                ['wcol' + Number(datas)]: e.meetName,
                date: dayjs(e.startTime).format('YYYY-MM-DD'),
                startHour: startHour,
              },
            ],
          });
        }
      });
    }
  } else if (dataFormat == 'day') {
    const res = await meetRoomApi.SelectUse({
      pageStatus: 3,
      queryDate: dayjs(dayjs(dateValue.value)).format('YYYY-MM-DD'),
    });
    if (res.code == 0) {
      const arr = res.data;
      const seenKeyids = new Set<number>();
      arr.map(e => {
        let startHour =
          dayjs(e.startTime).format('HH:mm') +
          '-' +
          dayjs(e.endTime).format('HH:mm');
        // 判断是否数据的keyid存在，存在将数据合并到最开始出现的数据的textarr字段里，不存在则将新增keyid并添加数据到textarr
        if (seenKeyids.has(e.keyid)) {
          tabData.value.forEach(item => {
            if (item.keyid == e.keyid) {
              item.textArr.push({
                conName: e.conName,
                meetName: e.meetName,
                ['dcol' + numberC(dayjs(e.startTime).format('HH'))]: e.meetName,
                date: dayjs(e.startTime).format('YYYY-MM-DD'),
                startHour: startHour,
                keyid: e.keyid,
              });
            }
          });
        } else {
          seenKeyids.add(e.keyid);
          tabData.value.push({
            conName: e.conName,
            meetName: e.meetName,
            ['dcol' + numberC(dayjs(e.startTime).format('HH'))]: e.meetName,
            date: dayjs(e.startTime).format('YYYY-MM-DD'),
            startHour: startHour,
            keyid: e.keyid,
            textArr: [
              {
                conName: e.conName,
                meetName: e.meetName,
                ['dcol' + numberC(dayjs(e.startTime).format('HH'))]: e.meetName,
                date: dayjs(e.startTime).format('YYYY-MM-DD'),
                startHour: startHour,
                keyid: e.keyid,
              },
            ],
          });
        }
      });
    }
  }
};

// 初始化列表数据
const initTabDatas = () => {};

// 日期切换
const beforeAndNext = async (type: number) => {
  // 上一事件切换
  if (type == 1) {
    switch (calenderType.value) {
      case 'month':
        dateValue.value = dayjs(dateValue.value)
          .subtract(1, 'month')
          .format('YYYY-MM-DD');
        initColumns();
        break;
      case 'week':
        let tWeek = dayjs(dateValue.value).day();
        let minMax = tWeek + 1;
        dateValue.value = dayjs(dateValue.value)
          .subtract(minMax, 'day')
          .format('YYYY-MM-DD');
        initColumns();
      case 'day':
        dateValue.value = dayjs(dateValue.value)
          .subtract(1, 'day')
          .format('YYYY-MM-DD');
        getWorkDate();
        initColumns();
    }
  }
  // 下一事件切换
  else if (type == 2) {
    switch (calenderType.value) {
      case 'month':
        dateValue.value = dayjs(dateValue.value)
          .add(1, 'month')
          .format('YYYY-MM-DD');
        initColumns();
        break;
      case 'week':
        let tWeek = dayjs(dateValue.value).day();
        let weekMax = 7 - tWeek + 1;
        dateValue.value = dayjs(dateValue.value)
          .add(weekMax, 'day')
          .format('YYYY-MM-DD');
        initColumns();
      case 'day':
        dateValue.value = dayjs(dateValue.value)
          .add(1, 'day')
          .format('YYYY-MM-DD');
        getWorkDate();
        initColumns();
    }
  }
  // 事件触发查询请求
  await getSearch(calenderType.value);
};

watch(
  () => calenderType.value,
  () => {
    initColumns();
  }
);

watch(
  () => calenderType.value,
  async () => {
    await getSearch(calenderType.value);
  }
);
</script>

<style lang="scss">
.u-custom-calender {
  background-color: #fff;
  .u-exchange-icon {
    padding: 6px;
    border: 1px solid;
    border-radius: 4px;
  }

  .u-current-date {
    padding: 0;

    input {
      text-align: center;
      font-family: PingFang SC Medium, PingFang SC Medium;
      font-weight: 400;
      font-size: 14px;
      color: #333333;
    }

    .ant-picker-suffix {
      display: none;
    }
  }
  tr {
    height: 8vh !important;
  }
  tr:first-child {
    height: 0 !important;
  }
  .u-my-calender-month {
    .ant-picker-content {
      thead {
        tr {
          height: 30px;
        }
      }

      tbody {
        border: 1px solid #e9e9e9;
        border-bottom: none;

        .ant-picker-cell-selected {
          background: #e6f4ff !important;
          color: #1677ff !important;
        }

        .u-custome-calender-cell {
          width: 100%;
          height: var(--height);
          padding: 10px;
          text-align: left;
          border-right: 1px solid #e9e9e9;
          border-bottom: 1px solid #e9e9e9;
          box-sizing: border-box;
        }
      }

      .ant-picker-cell {
        padding: 0;
      }
    }
  }

  .u-calender-cell-work {
    height: calc(100% - 22px);
    overflow: auto;
    padding-left: 4px;
    background-color: var(bg);
    border-radius: 2px 2px 2px 2px;
    color: var(--fc);

    .u-calend-work-area {
      margin-bottom: 4px;
      padding: 4px 2px;
      font-family: PingFang SC, PingFang SC;
      font-weight: 400;
      font-size: 12px;
      color: #1890ff;
      background: #e7f4ff;
      border-left: 2px solid #1890ff;
      border-radius: 2px 2px 2px 2px;
    }
  }

  .u-day-week-table {
    .ant-table-thead {
      .ant-table-cell {
        background-color: #f2f2f2;
      }
    }

    .ant-table-body {
      .ant-table-cell {
        padding: 0 8px !important;
        background-color: #fff;
      }
    }
  }
}
</style>
